package com.xb.loan.fund.impl;

import com.xb.loan.account.service.ICashService;
import com.xb.loan.account.service.bean.CashInfoVO;
import com.xb.loan.account.service.constant.AccountConst;
import com.xb.loan.cashier.service.constant.ICashierEnumConst;
import com.xb.loan.encryptor.crypt.Encryptor;
import com.xb.loan.encryptor.crypt.EncryptorManager;
import com.xb.loan.fund.common.VerifySet;
import com.xb.loan.fund.dao.CashChargeDao;
import com.xb.loan.fund.dao.bean.CashCharge;
import com.xb.loan.fund.dao.bean.CashChargeRec;
import com.xb.loan.fund.dao.bean.StatUserCharge;
import com.xb.loan.fund.service.ICashChargeService;
import com.xb.loan.fund.service.ICashVerifyErrorService;
import com.xb.loan.fund.service.IFundService;
import com.xb.loan.fund.service.bean.*;
import com.xb.loan.fund.service.bean.*;
import com.xb.loan.fund.service.constant.FundConst;
import com.xb.loan.fund.service.exception.IFundServiceException;
import com.xb.loan.log.exception.BizException;
import com.xb.loan.log.exception.IBizException;
import com.xb.loan.usercenter.service.user.IUserService;
import com.xb.loan.usercenter.service.user.IUserThresholdService;
import com.xb.loan.usercenter.service.user.bean.UserInfoVO;
import com.xb.loan.usercenter.service.user.bean.UserThresholdVO;
import com.xb.loan.usercenter.service.user.constant.UserConst;
import com.xb.loan.util.StringUtils;
import com.xb.loan.util.cache.redis.comm.FormatOperation;
import com.xb.loan.util.common.ObjectOperation;
import com.xb.loan.util.log.DefaultLoggerFacotry;
import com.xb.loan.util.log.LogFormatUtil;
import com.xb.loan.util.mybatis.MyTransactional;
import com.xb.loan.util.refself.BeanSelfAware;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 类 描述 : 现金充值业务接口实现
 */
@Service("cashChargeService")
public class CashChargeServiceImpl implements ICashChargeService, BeanSelfAware {

	private static Logger logger = DefaultLoggerFacotry.getLogger(CashChargeServiceImpl.class);
	
	// 加密算法（用于与收银台通讯）
	Encryptor partnerEncrytor = EncryptorManager.getEncryptor("partner");
	// 加密算法（用于本地防篡改）
	Encryptor userEncrytor = EncryptorManager.getEncryptor("user");
	
	@Value("${cashier.charge.url}")
	private String cashierChargeUrl;
	
	private CashChargeServiceImpl proxySelf; // ② 表示代理对象，不是目标对象

	public void setSelf(Object proxyBean) { // 通过InjectBeanSelfProcessor注入自己（目标对象）的AOP代理对象
		this.proxySelf = (CashChargeServiceImpl) proxyBean;
	}

	/*
	 * @Autowired //① 注入上下文 private ApplicationContext context;
	 * 
	 * private FundServiceImpl proxySelf; //② 表示代理对象，不是目标对象
	 * 
	 * @PostConstruct //③ 初始化方法 private void setSelf() {
	 * //从上下文获取代理对象（如果通过proxtSelf=this是不对的，this是目标对象） //此种方法不适合于prototype
	 * Bean，因为每次getBean返回一个新的Bean proxySelf = (FundServiceImpl)
	 * context.getBean(FundService.class); }
	 */

	@Autowired
	private ICashService cashService;

	@Autowired
	private CashChargeDao cashChargeDao;

	@Autowired
	private IUserService userService;

	@Autowired
	private IUserThresholdService userThresholdService;

	@Autowired
	private ICashVerifyErrorService cashVerifyErrorService;

	//@Autowired
	//private IOrderService orderService;

	
	@Override
	public ChargeApplyVO charge(CashChargeVO cashChargeVO) throws BizException {
		// 验证用户信息
		UserInfoVO userInfoVO = userService.queryUserInfoById(cashChargeVO.getUserId());
		VerifySet.verifyUserInfoVOIsNormal(userInfoVO);
		//VerifySet.verifyUserRelation2Partner(userInfoVO,  "charge");
		
		// 验证充值是否超出阈值上
		if(userInfoVO.getUserLevel() != UserConst.UserLevel.CHANNEL.getCode()){
			/**
			 * wuqinglong
			 * 实际应用的时候再处理，原来这里是通过渠道查询，这里没有渠道了以后具体的问题具体分析处理
			 */
			UserThresholdVO userThresholdVO = userThresholdService.selectByKey("100000");
			verifyChargeThreshold(userInfoVO, userThresholdVO, cashChargeVO);
		}
		
		CashCharge cashCharge = new CashCharge();
		cashCharge.setPid(cashChargeVO.getPid());
		cashCharge.setUserId(cashChargeVO.getUserId());
		cashCharge.setUserLevel(userInfoVO.getUserLevel());
		cashCharge.setAccountId(userInfoVO.getAccountId());
		cashCharge.setMoney(cashChargeVO.getMoney());
		cashCharge.setPaychannelType(cashChargeVO.getPaychannelType());
		cashCharge.setPaychannelName(cashChargeVO.getPaychannelName());
		cashCharge.setCreateTime(FormatOperation.formatDateToYMDHms14(new Date()));
		cashCharge.setUserType(userInfoVO.getUserType());
		// 订单Id生成
		cashCharge.setChargeId(FormatOperation.assemblySeq(FundConst.PriKey_Name, FundConst.PriKey_Length));
		if(StringUtils.isEmpty(cashCharge.getPid())){
			cashCharge.setPid(cashCharge.getChargeId());
		}
		
		// 验证是否是重复订单
		verifyRepeatOrder(cashCharge);
		
		// 设置渠道的支付渠道集合
		/*PartnerInfoVO partnerInfoVO = partnerInfoService.selectByPrimaryKey(cashChargeVO.getPartnerId());
		if(StringUtils.isEmpty(partnerInfoVO.getCashierPlatId())){
			logger.warn(LogFormatUtil.getFormatMsg(new String[]{"module", "partnerId", "msg"},
					new Object[]{"charge", cashChargeVO.getPartnerId(),
					IPartnerServiceException.chargeIsNotSupported.getMessage()}));
			throw IPartnerServiceException.chargeIsNotSupported;
		}else{
			cashCharge.setPlatId(partnerInfoVO.getCashierPlatId());
		}*/
		
		// 若为在线支付购彩订单，需在充值成功后通知购彩模块，此处设置通知状态
		if (cashCharge.getOrderId() != null){
			cashCharge.setOrderId(cashChargeVO.getOrderId());
			cashCharge.setBenifitUserId(cashChargeVO.getBenifitUserId());
			cashCharge.setInformPurchase(FundConst.InformPurchase_Wait);
		}
		// 使用“user模式”生成签名信息，防止本地篡改
		String digitalSign = userEncrytor.encrypt(cashCharge.getUserId(), cashCharge.getChargeId(), generateKey(cashCharge));
		cashCharge.setDigitalSign(digitalSign);
		// 设置订单状态
		cashCharge.setStatus(FundConst.ChargeStatus_Wait); 
		// 设置账期
		cashCharge.setAccountPeriod(FormatOperation.formatDateToYMD(new Date()));
		
		this.cashChargeDao.insertCashChargeTmp(cashCharge);
		
		return generateCashierParam(cashCharge, userInfoVO);
	}

	private void verifyRepeatOrder(CashCharge cashCharge) throws BizException {
		CashChargeVO cashChargeVO = proxySelf.queryCashChargeByPid(cashCharge.getPid());
		if(cashChargeVO != null){
			logger.warn(LogFormatUtil.getFormatMsg(new String[]{"module",  "pOrderId", "msg"},
					new Object[] { "charge", cashChargeVO.getPid(),
					IFundServiceException.RepeatOrder.getMessage()}));
			throw IFundServiceException.RepeatOrder;
		}
	}

	// 验证充值是否超出阈值
	private void verifyChargeThreshold(UserInfoVO userInfoVO, UserThresholdVO userThresholdVO,
			CashChargeVO cashChargeVO) throws BizException {
		if(userThresholdVO == null){
			logger.warn(LogFormatUtil.getFormatMsg(new String[]{"module",  "msg"},
					new Object[]{"charge",
					IFundServiceException.userThresholdNotExist.getMessage()}));
			throw IFundServiceException.userThresholdNotExist;
		}
		// 违反最大金额限制
		if (cashChargeVO.getMoney() > userThresholdVO.getMaxChargeMoney()) {
			logger.warn(LogFormatUtil.getFormatMsg(new String[]{"module", "userId", "money", "msg"},
					new Object[]{"charge", cashChargeVO.getUserId(), cashChargeVO.getMoney(),
					IFundServiceException.ViolateMaxMoneyLimit.getMessage()}));
			throw IFundServiceException.ViolateMaxMoneyLimit;
		}
		// 违反日操作最大次数限制
		int sumOptNumToday = cashChargeDao.querySumOptNumToday(userInfoVO.getUserId());
		if (sumOptNumToday >= userThresholdVO.getMaxChargeNum()) {
			logger.warn(LogFormatUtil.getFormatMsg(new String[]{"module", "userId", "sumOptNumToday", "msg"},
					new Object[]{"charge", cashChargeVO.getUserId(), sumOptNumToday,
					IFundServiceException.ViolateSumOptNumLimit.getMessage()}));
			throw IFundServiceException.ViolateSumOptNumLimit;
		}
	}

	/**
	 * 返回跳入收银台页面所需要的参数
	 * @param cashCharge
	 * @param userInfoVO 
	 * @return
	 * @throws BizException
	 * 2015年11月18日 by wenju.song
	 */
	private ChargeApplyVO generateCashierParam(CashCharge cashCharge, UserInfoVO userInfoVO)
			throws BizException {
		String encryptStr = generateKey(cashCharge);
		// 使用“partner模式”生成签名信息，保证和收银台安全通讯
		String digitalSign4Cashier = partnerEncrytor.encrypt(FundConst.Cashier_Cert, null, encryptStr);
		
		CashInfoVO cashInfoVO = cashService.queryCashInfoById(userInfoVO.getAccountId());
		
		// 线上充值业务，拼装收银台的充值URL
		ChargeApplyVO chargeApplyVO = new ChargeApplyVO();
		chargeApplyVO.setOrderId(cashCharge.getChargeId());
		chargeApplyVO.setUserId(cashCharge.getUserId());
		chargeApplyVO.setMoney(String.valueOf(cashCharge.getMoney()));
		chargeApplyVO.setPlatId(cashCharge.getPlatId());
		chargeApplyVO.setSign(digitalSign4Cashier);
		chargeApplyVO.setAccountPeriod(cashCharge.getAccountPeriod());
		chargeApplyVO.setPhone(userInfoVO.getPhone());
		chargeApplyVO.setAccountCash(String.valueOf(cashInfoVO.getMoney()));
		return chargeApplyVO;
	}

	@Override
	public ChargeApplyVO reCharge(CashChargeVO cashChargeVO) throws BizException {
		logger.debug(LogFormatUtil.getFormatMsg(new String[]{"module", "chargeId", "orderId"},
				new Object[]{"charge", cashChargeVO.getChargeId(), cashChargeVO.getOrderId()}));
		
		if(StringUtils.isEmpty(cashChargeVO.getChargeId()) && StringUtils.isEmpty(cashChargeVO.getOrderId())){
			logger.warn(LogFormatUtil.getFormatMsg(new String[]{"module", "msg"},
					new Object[] { "charge", "orderId和chargeId不能同时为空" }));
			throw IBizException.inputParameterIsWrong;
		}
		
		// 在线支付购彩
		if (StringUtils.isNotEmpty(cashChargeVO.getOrderId())) {
			Map<String, Object> param = new HashMap<String, Object>();
			param.put("orderId", cashChargeVO.getOrderId());
			List<CashCharge> cashCharges = cashChargeDao.queryAllCashChargeUnion(param);
			if (cashCharges == null || cashCharges.size() == 0) {
				logger.warn(LogFormatUtil.getFormatMsg(new String[]{"module", "orderId", "msg"},
						new Object[] { "charge", cashChargeVO.getOrderId(), "没有支付订单，应调用charge服务" }));
				throw IFundServiceException.chargeNotExist;
			}
			for (CashCharge cashCharge : cashCharges) {
				// 1、查看是否有待支付的充值订单
				if (cashCharge.getStatus() == FundConst.ChargeStatus_Wait) {
					UserInfoVO userInfoVO = userService.queryUserInfoById(cashCharge.getUserId());
					return generateCashierParam(cashCharge, userInfoVO);
				}
				// 2、查看是否有成功的充值订单
				if (cashCharge.getStatus() == FundConst.ChargeStatus_Success) {
					logger.warn(LogFormatUtil.getFormatMsg(new String[]{"module", "orderId", "msg"}, new Object[] { "charge",
							cashChargeVO.getOrderId(), "充值订单已成功，无法重新支付" }));
					throw IFundServiceException.chargeSucceed;
				}
			}

			// 从失败订单中任选一个，进行重新支付操作
			CashChargeVO cashChargeData = ObjectOperation.convertByClasses(cashCharges.get(0), CashChargeVO.class);
			return charge(cashChargeData);
		}
		
		// 单独的充值订单，chargeId一定不能为空
		CashCharge cashCharge = cashChargeDao.queryCashChargeById(cashChargeVO.getChargeId());
		// 1、处理中
		if (cashCharge.getStatus() == FundConst.ChargeStatus_Wait){
			UserInfoVO userInfoVO = userService.queryUserInfoById(cashCharge.getUserId());
			return generateCashierParam(cashCharge, userInfoVO);
		}
		// 2、成功
		if (cashCharge.getStatus() == FundConst.ChargeStatus_Success) {
			logger.warn(LogFormatUtil.getFormatMsg(new String[]{"module", "orderId", "msg"}, new Object[] {"charge",
					cashChargeVO.getOrderId(), IFundServiceException.chargeSucceed.getMessage()}));
			throw IFundServiceException.chargeSucceed;
		}
		// 3、失败
		CashChargeVO cashChargeData = ObjectOperation.convertByClasses(cashCharge, CashChargeVO.class);
		return charge(cashChargeData);

	}

	@Override
	public void chargeResult(ChargeResultVO chargeResultVO) throws BizException {
		logger.debug(chargeResultVO.toString());
		
		CashCharge cashCharge = cashChargeDao.queryCashChargeById(chargeResultVO.getChargeId());
		boolean repeatFlag = false;
		repeatFlag = verifyChargeResult(chargeResultVO, cashCharge);
		// 重复回调，直接返回
		if (repeatFlag)
			return;

		chargeResultInner(cashCharge, chargeResultVO.getPayChannelType(), chargeResultVO.generateResult(), 
				chargeResultVO.getPayCardType(), chargeResultVO.getPayCardName(), 
				chargeResultVO.getPayCardNo(), chargeResultVO.getForeignId());
	}

	/**
	 * 充值结果返回操作
	 * @param payChannelType 充值渠道类型
	 * @param status 充值状态
	 * @param payCardType 支付卡类型
	 * @param payCardName 支付卡户名
	 * @param payCardNo 支付卡号码
	 * @param foreignId 收银台充值订单ID
	 * 2016年1月28日 by wenju.song 
	 * @throws BizException 
	 */
	public void chargeResultInner(CashCharge cashCharge, int payChannelType, int status, Integer payCardType, String payCardName,
                                  String payCardNo, String foreignId) throws BizException {
		// 设置充值渠道类型
		cashCharge.setPaychannelType(payChannelType);
		cashCharge.setPaychannelName(ICashierEnumConst.CashierPayChannelType.getPayChannelName(payChannelType));
		
		// 设置充值结果
		cashCharge.setStatus(status);
		// 设置充值支付卡信息
//		if(payCardType != null){
//			cashCharge.setBankCode(payCardType);
//			cashCharge.setBankName(payCardName);
//			cashCharge.setCardNo(payCardNo);
//			payOrgVO = payOrgService.selectByPayOrgCode(payCardType);
//			cashCharge.setCardName(payOrgVO.getPayorgName());
//		}
		// 设置对账状态
		cashCharge.setAccountStatus(FundConst.CheckAccountStatus_Wait);
		// 设置收银台记录ID
		cashCharge.setCashierOrderId(foreignId);
		
		UserInfoVO userInfoVO = userService.queryUserInfoById(cashCharge.getUserId());
		
		proxySelf.chargeResultTransaction(cashCharge, userInfoVO);
		
		// 在线充值购彩订单，若充值成功，通知购彩模块扣钱出票
		if (status == FundConst.ChargeStatus_Success && StringUtils.isNotEmpty(cashCharge.getOrderId())) {
			orderService.handlerTradeOnLine(cashCharge.getOrderId(), cashCharge.getBenifitUserId());
			Map<String, Object> params = new HashMap<String, Object>();
			params.put("chargeId", cashCharge.getChargeId());
			params.put("informPurchase", FundConst.InformPurchase_Done);
			cashChargeDao.updateCashChargeById(params);
		}
	}

	/**
	 * 
	 * 充值结果返回事务操作
	 * 
	 * @param cashCharge
	 * @param userInfoVO
	 * @throws BizException 2015年9月7日 by zhangyi
	 */
	@MyTransactional
	public void chargeResultTransaction(CashCharge cashCharge, UserInfoVO userInfoVO) throws BizException {
		// 删除临时表数据
		cashChargeDao.deleteCashChargeTmpById(cashCharge.getChargeId());
		// 转移数据
		cashChargeDao.insertCashCharge(cashCharge);
		// 充值成功加钱
		if (cashCharge.getStatus() == FundConst.ChargeStatus_Success) {
			cashService.addMoney(cashCharge.getChargeId(), userInfoVO, cashCharge.getMoney(), 
					AccountConst.BillType_Charge, cashCharge.getAccountPeriod());
		}
	}

	// 充值结果返回验证--操作
	private boolean verifyChargeResult(ChargeResultVO chargeResultVO, CashCharge cashCharge) throws BizException {
		// 充值订单不存在
		if (cashCharge == null ){
			logger.error(LogFormatUtil.getFormatMsg(new String[]{"module", "chargeId", "msg"},
					new Object[]{"charge_result", chargeResultVO.getChargeId(), IFundServiceException.chargeNotExist.getMessage()}));
			throw IFundServiceException.chargeNotExist;
		}
		
		// 充值订单为成功、失败，均不继续处理
		if (cashCharge.getStatus() != FundConst.ChargeStatus_Wait){
			logger.warn(LogFormatUtil.getFormatMsg(new String[]{"module", "chargeId", "msg"},
					new Object[]{"charge_result", chargeResultVO.getChargeId(), "充值状态非处理中，忽略此次通知。"}));
			return true;
		}
		
		String encryptStr = chargeResultVO.generateKey();
		// 解密签名(收银台的公钥) --》 对比结果 收银台数据是否被篡改
		if (!partnerEncrytor.encryptValidate(FundConst.Cashier_Cert, null, encryptStr, chargeResultVO.getDigitalSign())) {// 收银台验签失败
			// 将回调数据保存到验证异常表（T_Cash_VerifyError）
			CashVerifyErrorVO cashVerifyErrorVO = generateVerifyErrorVO(cashCharge, chargeResultVO, FundConst.VerifyErrorType_CASHIERERROR);
			cashVerifyErrorService.addCashVerifyError(cashVerifyErrorVO);
			
			logger.warn(LogFormatUtil.getFormatMsg(new String[]{"module", "cashierOrderId", "msg"},
					new Object[]{"charge_result", chargeResultVO.getForeignId(), IFundServiceException.cashierDataIsBeDistort.getMessage()}));
			throw IFundServiceException.cashierDataIsBeDistort;
		}

		// 本地数据重新加密（平台的私钥） 验证本地数据是否被篡改了
		String localEncryptStr = generateKey(cashCharge);
		if (!userEncrytor.encryptValidate(cashCharge.getUserId(), cashCharge.getChargeId(), localEncryptStr,
				cashCharge.getDigitalSign())) {
			// 本地数据，验签失败
			CashVerifyErrorVO cashVerifyErrorVO = generateVerifyErrorVO(cashCharge, chargeResultVO, FundConst.VerifyErrorType_LOCALERROR);
			cashVerifyErrorService.addCashVerifyError(cashVerifyErrorVO);
			
			logger.warn(LogFormatUtil.getFormatMsg(new String[]{"module", "cashierOrderId", "msg"},
					new Object[]{"charge_result", chargeResultVO.getForeignId(), IFundServiceException.localDataIsBeDistort.getMessage()}));
			throw IFundServiceException.localDataIsBeDistort;
		}

		// 本地数据没有篡改，则验证本地的数据与收银台返回的时候是否一致 (充值平台ID 充值用户ID 渠道ID 充值金额)要保持一致
		if (!cashCharge.getPlatId().equals(chargeResultVO.getPlatId())
				|| !cashCharge.getUserId().equals(chargeResultVO.getUserId())
				|| cashCharge.getMoney() != chargeResultVO.getMoney()) {

			CashVerifyErrorVO cashVerifyErrorVO = generateVerifyErrorVO(cashCharge, chargeResultVO, FundConst.VerifyErrorType_DATADIFFER);
			cashVerifyErrorService.addCashVerifyError(cashVerifyErrorVO);
			logger.warn(LogFormatUtil.getFormatMsg(new String[]{"module", "cashierOrderId", "msg"},
					new Object[]{"charge_result", chargeResultVO.getForeignId(),
					IFundServiceException.TheLocalDataAndTransactionDataAreDifferent.getMessage()}));
			throw IFundServiceException.TheLocalDataAndTransactionDataAreDifferent;
		}
		return false;
	}
	
	private CashVerifyErrorVO generateVerifyErrorVO(CashCharge cashCharge, ChargeResultVO chargeResultVO, int verifyErrorType){
		CashVerifyErrorVO cashVerifyErrorVO = new CashVerifyErrorVO();
		if(cashCharge != null){
			cashVerifyErrorVO.setOrderId(cashCharge.getChargeId());
			cashVerifyErrorVO.setUserId(cashCharge.getUserId());
			cashVerifyErrorVO.setPlatId(cashCharge.getPlatId());
			cashVerifyErrorVO.setMoney(cashCharge.getMoney());
			cashVerifyErrorVO.setDigitalSign(cashCharge.getDigitalSign());
		}
		if(chargeResultVO != null){
			cashVerifyErrorVO.setCashierOrderId(chargeResultVO.getChargeId());
			cashVerifyErrorVO.setCashierUserId(chargeResultVO.getUserId());
			cashVerifyErrorVO.setCashierPlatId(chargeResultVO.getPlatId());
			cashVerifyErrorVO.setCashierMoney(chargeResultVO.getMoney());
			cashVerifyErrorVO.setCashierReturnCode(Integer.valueOf(chargeResultVO.getReturnCode()));
			cashVerifyErrorVO.setCashierDigitalSign(chargeResultVO.getDigitalSign());
		}

		cashVerifyErrorVO.setFundLimitId(FormatOperation.assemblySeq(FundConst.PriKey_Name, FundConst.PriKey_Length));
		cashVerifyErrorVO.setStatus(FundConst.VerifyErrorStatus_Wait);
		cashVerifyErrorVO.setOrderType(FundConst.FundType_Charge);
		cashVerifyErrorVO.setErrorType(verifyErrorType);
		
		return cashVerifyErrorVO;
	}


    public void clearAccountStatus(String accountPeriod){
        cashChargeDao.clearAccountStatus(accountPeriod);
    }
    
    public int updateAccountStatus(String chargeId, int accountStatus) throws BizException{
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("chargeId", chargeId);
        params.put("accountStatus", accountStatus);
        
        return cashChargeDao.updateCashChargeById(params);
    }
    
    @Override
    public List<Map<String, Object>> statChargeDay(Map<String, Object> params) {
        return cashChargeDao.statChargeDay(params);
    }

	@Override
	public List<CashChargeVO> queryChargeOrder(String userId, Integer payChannelType, Integer status,
                                               String partnerId, String startDate, String endDate, int pageNum, int numPerPage) throws BizException {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("userId", userId);
		params.put("payChannelType", payChannelType);
		params.put("status", status);
		params.put("partnerId", partnerId);
		params.put("startDate", FormatOperation.formatY_M_DHmsToYMDHms14(startDate));
		params.put("endDate", FormatOperation.formatY_M_DHmsToYMDHms14(endDate));
		params.put("pageNum", pageNum);
		params.put("numPerPage", numPerPage);

		List<CashCharge> list = cashChargeDao.queryCashChargeUnion(params);

		List<CashChargeVO> listResult = ObjectOperation.convertByClassesList(list, CashChargeVO.class);
		if(listResult != null){
		    for(CashChargeVO chargeVO : listResult)
		        chargeVO.setCreateTime(FormatOperation.formatYMDHms14ToY_M_DHms(chargeVO.getCreateTime()));
		}

		return listResult;
	}

	@Override
	public int queryChargeOrderCount(String userId, Integer payChannelType, Integer status,
                                     String partnerId, String startDate, String endDate) throws BizException {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("userId", userId);
		params.put("payChannelType", payChannelType);
		params.put("status", status);
		params.put("partnerId", partnerId);
		params.put("startDate", FormatOperation.formatY_M_DHmsToYMDHms14(startDate));
        params.put("endDate", FormatOperation.formatY_M_DHmsToYMDHms14(endDate));

		Integer retNum = cashChargeDao.queryCashChargeUnionCount(params);

		return retNum;
	}
	
	public CashChargeVO queryCashChargeByPid(String pid) throws BizException{
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("pid", pid);
		CashCharge cashCharge = cashChargeDao.queryCashChargeByPid(params);
		if(cashCharge != null)
		    cashCharge.setCreateTime(FormatOperation.formatYMDHms14ToY_M_DHms(cashCharge.getCreateTime()));
		return ObjectOperation.convertByClasses(cashCharge, CashChargeVO.class);
	}

	/**
	 * 生成待加密字符串 顺序：money、platId、userId、orderId
	 * @param cashCharge
	 * @return
	 */
	private String generateKey(CashCharge cashCharge){
		StringBuffer sb = new StringBuffer();
		String strCentor = FundConst.Encrypt_Field_Splitter;
		sb.append(IFundService.df.format(cashCharge.getMoney()));
		sb.append(strCentor);
		sb.append(cashCharge.getPlatId());
		sb.append(strCentor);
		sb.append(cashCharge.getUserId());
		sb.append(strCentor);
		sb.append(cashCharge.getChargeId());
		
		return sb.toString();
	}

	@Override
	public CashChargeVO queryCashChargeById(String chargeId) throws BizException {
		CashCharge cashCharge = cashChargeDao.queryCashChargeById(chargeId);
		if(cashCharge != null)
            cashCharge.setCreateTime(FormatOperation.formatYMDHms14ToY_M_DHms(cashCharge.getCreateTime()));
		return ObjectOperation.convertByClasses(cashCharge, CashChargeVO.class);
	}

	@Override
	public CashChargeVO queryCashChargeByPid(String partnerId, String pid) throws BizException {
		return null;
	}

	@Override
	public List<CashChargeVO> queryAllCashCharge(String accountPeriod, Integer accountStatus, Integer status) {
	    Map<String, Object> params = new HashMap<String, Object>();
        params.put("accountPeriod", accountPeriod);
        params.put("accountStatus", accountStatus);
        params.put("status", status);
        
        List<CashCharge> list = cashChargeDao.queryAllCashCharge(params);
	    return ObjectOperation.convertByClassesList(list, CashChargeVO.class);
	}

	@Override
	public List<StatUserChargeVO> queryStatUserCharge(String statTime) {
		
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("statTime", statTime);
		List<StatUserCharge> sucList = cashChargeDao.queryStatUserCharge(map);
		return ObjectOperation.convertByClassesList(sucList, StatUserChargeVO.class);
	}

	@Override
	public int queryCashChargeTmpByAccountId(String accountId)
			throws BizException {
		
		return cashChargeDao.queryCashChargeTmpByAccountId(accountId);
	}

	@Override
	public List<CashChargeRecVO> queryCashChargeRec(Integer userType,
                                                    String startTime, String endTime, int pageNum, int numPerPage)
			throws BizException {

		Map<String, Object> map = new HashMap<String, Object>();
		map.put("userType", userType);
		map.put("startTime", startTime);
		map.put("endTime", endTime);
		map.put("pageNum", pageNum);
		map.put("numPerPage", numPerPage);
		List<CashChargeRec> chargeList = cashChargeDao.queryCashChargeRec(map);
		if(chargeList != null && chargeList.size()>0){
			return ObjectOperation.convertByClassesList(chargeList, CashChargeRecVO.class);
		}
		return null;
	}

	@Override
	public int queryCashChargeRecCount(Integer userType, String startTime,
                                       String endTime) throws BizException {

		Map<String, Object> map = new HashMap<String, Object>();
		map.put("userType", userType);
		map.put("startTime", startTime);
		map.put("endTime", endTime);
		return cashChargeDao.queryCashChargeRecCount(map);
	}
}
